package com.dd.cloud.user.service.resource.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.cloud.common.constants.IntegralConstants;
import com.dd.cloud.common.constants.ResourceConstants;
import com.dd.cloud.common.interceptor.UserInterceptor;
import com.dd.cloud.common.vo.LoginInfo;
import com.dd.cloud.user.entity.doctor.DoctorIntegral;
import com.dd.cloud.user.entity.resource.PostInfoOperCount;
import com.dd.cloud.user.mapper.resource.PostInfoOperCountMapper;
import com.dd.cloud.user.mq.MQConfig;
import com.dd.cloud.user.mq.RabbitSend;
import com.dd.cloud.user.service.doctor.IDoctorIntegralService;
import com.dd.cloud.user.service.log.ILogErrorService;
import com.dd.cloud.user.service.resource.IPostInfoOperCountService;
import com.dd.cloud.user.vo.DelayMqVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;

/**
 * @author Lx
 * @version 1.0
 * @date 2023/10/17
 */
@Slf4j
@Service
public class PostInfoOperCountServiceImpl extends ServiceImpl<PostInfoOperCountMapper, PostInfoOperCount> implements IPostInfoOperCountService {

    @Autowired
    private IDoctorIntegralService doctorIntegralService;


    @Autowired
    private RabbitSend rabbitSend;

    @Autowired
    private RedisTemplate redisTemplate;

    private static String likeKey = "integral:likeKey:";


    /**
     * 帖子操作数量
     *
     * @param postInfoId 帖子id
     * @param type       数量类型 1阅读数 2点赞数 3转发数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createPostInfoOperCount(Integer postInfoId, Integer type) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        PostInfoOperCount postInfoOperCount = new PostInfoOperCount();
        QueryWrapper<PostInfoOperCount> qw = new QueryWrapper<>();
        qw.lambda().eq(PostInfoOperCount::getPostInfoId, postInfoId);
        qw.lambda().eq(PostInfoOperCount::getType, type);
        qw.lambda().eq(PostInfoOperCount::getUserId, loginInfo.getId());
        qw.lambda().eq(PostInfoOperCount::getUserType, loginInfo.getType());
        qw.lambda().eq(PostInfoOperCount::getStatus, ResourceConstants.PostInfoOperCountStatus.NORMAL);
        if (type == ResourceConstants.PostInfoOperCountType.READ) {
            PostInfoOperCount one = getOne(qw);
            if (one == null) {
                postInfoOperCount.setPostInfoId(postInfoId);
                postInfoOperCount.setType(type);
                postInfoOperCount.setUserId(loginInfo.getId());
                postInfoOperCount.setUserType(loginInfo.getType());
                postInfoOperCount.setStatus(ResourceConstants.PostInfoOperCountStatus.NORMAL);
                postInfoOperCount.setCreateDate(LocalDateTime.now());
                save(postInfoOperCount);
            }
        } else if (type == ResourceConstants.PostInfoOperCountType.LIVE) {
            PostInfoOperCount one = getOne(qw);
            if (one != null) {
                postInfoOperCount.setId(one.getId());
                postInfoOperCount.setStatus(ResourceConstants.PostInfoOperCountStatus.DEL);
                LocalDate preLocalDate = one.getCreateDate().toLocalDate();
                LocalDate nowLocalDate = LocalDateTime.now().toLocalDate();
                log.info("点赞时间:{}", preLocalDate);
                log.info("当前时间:{}", nowLocalDate);
                if (preLocalDate.isEqual(nowLocalDate)) {
                    LambdaQueryWrapper<DoctorIntegral> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(DoctorIntegral::getPostId, postInfoId)
                            .in(DoctorIntegral::getStatus, 0, 2, 3)
                            .last("limit 1");
                    DoctorIntegral doctorIntegral = doctorIntegralService.getOne(queryWrapper);
                    if (doctorIntegral != null) {
                        if (doctorIntegral.getStatus() == 0) {
                            doctorIntegral.setStatus(4);
                            doctorIntegralService.updateById(doctorIntegral);
                        } else if (doctorIntegral.getStatus() == 2
                                || doctorIntegral.getStatus() == 3) {
                            DoctorIntegral newDoctorIntegral = new DoctorIntegral();
                            newDoctorIntegral.setTitle("互动奖励收回").setDoctorId(loginInfo.getId())
                                    .setType(type)
                                    .setStatus(IntegralConstants.status.RETURN)
                                    .setType(type)
                                    .setEndDate(LocalDateTime.now().plusDays(1))
                                    .setCreateDate(LocalDateTime.now())
                                    .setNum(-2)
                                    .setPostId(postInfoId);
                            Boolean flag = doctorIntegralService.save(doctorIntegral);
                        }
                    }
//                    DoctorIntegral doctorIntegral = new DoctorIntegral();
                }
            } else {
                postInfoOperCount.setPostInfoId(postInfoId);
                postInfoOperCount.setType(type);
                postInfoOperCount.setUserId(loginInfo.getId());
                postInfoOperCount.setUserType(loginInfo.getType());
                postInfoOperCount.setStatus(ResourceConstants.PostInfoOperCountStatus.NORMAL);
                postInfoOperCount.setCreateDate(LocalDateTime.now());
                if (loginInfo.getType() == 1) {
                    like(loginInfo.getId(), IntegralConstants.IntegralType.TWENTY_TWO, postInfoId);
                }

            }
            saveOrUpdate(postInfoOperCount);
        } else if (type == ResourceConstants.PostInfoOperCountType.FORWARD) {
            postInfoOperCount.setPostInfoId(postInfoId);
            postInfoOperCount.setType(type);
            postInfoOperCount.setUserId(loginInfo.getId());
            postInfoOperCount.setUserType(loginInfo.getType());
            postInfoOperCount.setStatus(ResourceConstants.PostInfoOperCountStatus.NORMAL);
            postInfoOperCount.setCreateDate(LocalDateTime.now());
            save(postInfoOperCount);
        }
    }

    public void like(Integer doctorId, Integer type, Integer postId) {
        Integer num = (Integer) redisTemplate.opsForValue().get(likeKey + type + ":" + doctorId);
        if (num == null) {
            Boolean flag = saveDoctorIntegral(type, doctorId, "活跃奖励", 2, postId);
            if (flag) {
                Long time = 60 * 60 * 24 * 7L;
                redisTemplate.opsForValue().set(likeKey + type + ":" + doctorId, 2, time, TimeUnit.SECONDS);
                log.info("活跃积分奖励获取成功");
            }
        } else {
            if (num < 20) {
                Boolean flag = saveDoctorIntegral(type, doctorId, "活跃奖励", 2, postId);
                if (flag) {
                    log.info("活跃积分奖励获取成功");
                    Long time = redisTemplate.getExpire(likeKey + type + ":" + doctorId);
                    redisTemplate.opsForValue().set(likeKey + type + ":" + doctorId, num + 2, time, TimeUnit.SECONDS);
                }
            }
        }
    }

    @Autowired
    private ILogErrorService logErrorService;

    public Boolean saveDoctorIntegral(Integer type, Integer doctorId, String title, Integer num, Integer postId) {
        DoctorIntegral doctorIntegral = new DoctorIntegral();
        doctorIntegral.setTitle(title).setDoctorId(doctorId)
                .setType(type)
                .setStatus(IntegralConstants.status.AWAITING)
                .setType(type)
                .setEndDate(LocalDateTime.now().plusDays(1))
                .setCreateDate(LocalDateTime.now())
                .setNum(num)
                .setPostId(postId);
        Boolean flag = doctorIntegralService.save(doctorIntegral);
        if (!flag) {
            logErrorService.presBackLog("积分奖励失败", "保存积分失败", "doctorId=" + doctorId + ",type=" + type);
        }
        if (flag) {
            //毫秒级 24小时
            DelayMqVo<Integer> delayMqVo = new DelayMqVo<>();
            delayMqVo.setT(doctorIntegral.getId());
            delayMqVo.setType(DelayMqVo.DelayMqVoType.DOCTOR_INTEGRAL_MSG);
            long ms2 = 1000 * 60 * 60 * 24;
            rabbitSend.sendMessageDelay(MQConfig.DELAY_EXCHANGE, MQConfig.DELAY_KEY, delayMqVo, ms2);
        }
        return flag;
    }
}
